package com.xdf.whiteaccount.service.impl;

import com.xdf.whiteaccount.dao.CpBillfhMapper;
import com.xdf.whiteaccount.dao.DyeFabricInboundMapper;
import com.xdf.whiteaccount.dao.ProductOutwardOrderMapper;
import com.xdf.whiteaccount.entity.CpBillfh;
import com.xdf.whiteaccount.entity.DyeFabricInbound;
import com.xdf.whiteaccount.entity.SysConfigDecimal;
import com.xdf.whiteaccount.enums.ConfigDecimalEnum;
import com.xdf.whiteaccount.enums.PriceStandard;
import com.xdf.whiteaccount.enums.ResponseEnum;
import com.xdf.whiteaccount.service.SysConfigDecimalService;
import com.xdf.whiteaccount.service.base.BaseService;
import com.xdf.whiteaccount.utils.Example;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.xdf.whiteaccount.entity.DyeFabricPlan;

import java.math.BigDecimal;
import java.util.*;

import com.xdf.whiteaccount.dao.DyeFabricPlanMapper;
import com.xdf.whiteaccount.service.DyeFabricPlanService;
import org.springframework.util.Assert;

import javax.annotation.Resource;

/**
 * @Description : com.xdf.whiteaccount.service.impl(业务层实现类,该类为生成器自动生成).
 * @Author : 张柯
 * @Date : 2021-06-23 16:01:16
 */
@Service
public class DyeFabricPlanServiceImpl extends BaseService implements DyeFabricPlanService {
    @Autowired
    private DyeFabricPlanMapper dao;
    @Autowired
    private CpBillfhMapper cpBillfhMapper;
    @Autowired
    private DyeFabricInboundMapper dyeFabricInboundMapper;
    @Autowired
    private ProductOutwardOrderMapper productOutwardOrderMapper;
    @Autowired
    private SysConfigDecimalService sysConfigDecimalService;
    @Autowired(required = false)
    private SysConfigDecimal sysConfigDecimal;

    /**
     * @Describe 新增方法
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insert(DyeFabricPlan record) throws Exception {
        return dao.insert(record);
    }

    /**
     * @Describe 选择新增
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertSelective(DyeFabricPlan record) throws Exception {
        return dao.insertSelective(record);
    }

    /**
     * @Describe 批量新增
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiInsert(List<DyeFabricPlan> list) throws Exception {
        return dao.multiInsert(list);
    }

    /**
     * @Describe 修改
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKey(DyeFabricPlan record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * 检查纸管重量
     * @return
     */
    @SneakyThrows
    public Boolean checkPaperTube(DyeFabricPlan record){
        // 纸管、袋重、空加、空加隐藏
        // 1. 纸管
        // 1.1. 纸管是空或者0则合法
        // 1.2. 纸管重非0就要判断上限、下限
        Assert.notNull(record,"传入的计划单数据为空，不可保存！");
        BigDecimal paperTube = Optional.ofNullable(record.getPapertube()).orElse(BigDecimal.valueOf(0));
        int compared = paperTube.compareTo(BigDecimal.valueOf(0));
        if( compared==0 ){// 纸管重量为0,直接合法，返回数据
            //return dao.updateByPrimaryKeySelective(record);
            return true;
        }
        // 1.2. 判断上限、下限
        SysConfigDecimal configDecimal1 = sysConfigDecimalService.selectByPrimaryKey("纸管（kg）");
        BigDecimal big = configDecimal1.getConfig_bigvalue();
        BigDecimal small = configDecimal1.getConfig_smallvalue();
        int diff1 = paperTube.compareTo(big);
        int diff2 = paperTube.compareTo(small);
        // 前端的纸管重量和配置参数的上限比较
        // 用户数据大于参数则非法，不可保存
        if( diff1 >= 1 )
            throw new RuntimeException("纸管重" + paperTube + " 大于上限" + big + "，请修改纸管重量后再保存！");
        if( diff2 <= -1 )
            throw new RuntimeException("纸管重" + paperTube + " 小于下限" + small + "，请修改纸管重量后再保存！");

        return true;
    }

    /**
     * 检查袋重重量
     * @param record
     * @return
     */
    @SneakyThrows
    public boolean checkBagweight(DyeFabricPlan record){
        Assert.notNull(record,"传入的计划单数据为空，不可保存！");
        BigDecimal bagweight = Optional.ofNullable(record.getBagweight()).orElse(BigDecimal.valueOf(0));
        int compared1 = bagweight.compareTo(BigDecimal.valueOf(0));
        if( compared1==0 ){// 纸管重量为0,直接合法，返回数据
            return true;
        }
        SysConfigDecimal configDecimal2 = sysConfigDecimalService.selectByPrimaryKey("袋重（kg）");
        BigDecimal big2 = configDecimal2.getConfig_bigvalue();
        BigDecimal small2 = configDecimal2.getConfig_smallvalue();
        int diff3 = bagweight.compareTo(big2);
        int diff4 = bagweight.compareTo(small2);
        if (diff3 >= 1)
            throw new RuntimeException("袋重"+bagweight+"大于上限"+big2+",请修改袋重重量后再保存");
        if (diff4 <= -1)
            throw new RuntimeException("袋重"+bagweight+"小于上限"+small2+",请修改袋重重量后再保存");
        return true;
    }

    /**
     * 检查空加重量
     * @param record
     * @return
     */
    @SneakyThrows
    public boolean checkEmptyaddition(DyeFabricPlan record){
        Assert.notNull(record,"传入的计划单数据为空，不可保存！");
        BigDecimal emptyaddition = Optional.ofNullable(record.getEmptyaddition()).orElse(BigDecimal.valueOf(0));
        int compareTo2 = emptyaddition.compareTo(BigDecimal.valueOf(0));
        if (compareTo2 ==0 ) {
            return true;
        }
        SysConfigDecimal ConfigDecimal2 = sysConfigDecimalService.selectByPrimaryKey("空加（kg）");
        BigDecimal big3 = ConfigDecimal2.getConfig_bigvalue();
        BigDecimal small3 = ConfigDecimal2.getConfig_smallvalue();
        int diff5 = emptyaddition.compareTo(big3);
        int diff6 = emptyaddition.compareTo(small3);
        if (diff5 >=1 )
            throw new RuntimeException("空加"+emptyaddition+"大于上限"+big3+",请修改空加重量后再保存");
        if (diff6 <= -1 )
            throw new RuntimeException("空加"+emptyaddition+"小于上限"+small3+",请修改空加重量后再保存");
        return true;
    }

    /**
     * 检查空加隐藏重量
     * @param record
     * @return
     */
    @SneakyThrows
    public boolean checkEmptyadditionhide(DyeFabricPlan record){
        Assert.notNull(record,"传入的计划单数据为空，不可保存！");
        BigDecimal emptyadditionhide = Optional.ofNullable(record.getEmptyadditionhide()).orElse(BigDecimal.valueOf(0));
        int compareTo3 = emptyadditionhide.compareTo(BigDecimal.valueOf(0));
        if (compareTo3==0){
            return true;
        }
        SysConfigDecimal ConfigDecimal3 = sysConfigDecimalService.selectByPrimaryKey("空加隐藏（kg）");
        BigDecimal big4 = ConfigDecimal3.getConfig_bigvalue();
        BigDecimal small4 = ConfigDecimal3.getConfig_smallvalue();
        int diff7 = emptyadditionhide.compareTo(big4);
        int diff8 = emptyadditionhide.compareTo(small4);
        if (diff7 >=1 )
            throw new RuntimeException("空加"+emptyadditionhide+"大于上限"+big4+",请修改空加重量后再保存");
        if (diff8 <= -1 )
            throw new RuntimeException("空加"+emptyadditionhide+"小于上限"+small4+",请修改空加重量后再保存");
        return true;
    }
    /**
     * @Describe 选择修改
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateByPrimaryKeySelective(DyeFabricPlan record) throws Exception {
        // 检查纸管重
        if(!checkPaperTube(record)) return 0;
        // 检查袋重重
        if(!checkBagweight(record)) return 0;
        // 检查空加重
        if(!checkEmptyaddition(record)) return 0;
        // 检查空加隐藏重
        if(!checkEmptyadditionhide(record)) return 0;
        return dao.updateByPrimaryKeySelective(record);
    }


        /**
         * @Describe 修改
         * @author 张柯
         * @Date 2021-06-23 16:01:16
         */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int update(DyeFabricPlan record) throws Exception {
        return dao.updateByPrimaryKey(record);
    }

    /**
     * @Describe 批量修改
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int multiUpdate(List<DyeFabricPlan> list) throws Exception {
        return dao.multiUpdate(list);
    }

    /**
     * @Describe 根据主键查询
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    public DyeFabricPlan selectByPrimaryKey(Long id) throws Exception {
        return dao.selectByPrimaryKey(id);
    }

    /**
     * @Describe 根据主键删除
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @SuppressWarnings("unchecked")
    public int deleteByPrimaryKey(Long id) throws Exception {
        DyeFabricPlan record = dao.selectByPrimaryKey(id);
        Assert.notNull(record, "单据不存在或者已删除！");
        Assert.state(0 == record.getState(), "单据必须作废才允许删除！");
        Assert.state(cpBillfhMapper.countByExample(new Example().andEq("planid", record.getId())) <= 0, "当前计划有发货数据不允许删除");
        Assert.state(dyeFabricInboundMapper.countByExample(new Example().andEq("dye_plan_code", record.getPlanCode())) <= 0, "当前计划有入库或发货数据不允许删除");
        Assert.state(productOutwardOrderMapper.countByExample(new Example().andEq("plan_code", record.getId())) <= 0, "当前计划有外发数据不允许删除");
        return dao.deleteByPrimaryKey(id);
    }

    /**
     * @Describe 根据Entity查询
     * @author 张柯
     * @Date 2021-06-23 16:01:16
     */
    @Override
    public List<DyeFabricPlan> listQuery(DyeFabricPlan record) throws Exception {
        return dao.selectByParam(record);
    }

    /**
     * 根据主键作废
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelByPrimaryKey(Long id) {
        return dao.updateByPrimaryKeySelective(DyeFabricPlan.builder().id(id).cancelUserId(getLoginUserId()).state(0).upload(0).build());
    }

    /**
     * 恢复计划单
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int recoverByPrimaryKey(Long id) {
        return dao.updateByPrimaryKeySelective(DyeFabricPlan.builder().id(id).cancelUserId(0).state(1).upload(0).build());
    }

    /**
     * 设置完工状态
     *
     * @param id       计划主键
     * @param finished 完工标记
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int setFinishedMark(Long id, boolean finished) {
        DyeFabricPlan record = dao.selectByPrimaryKey(id);
        Assert.state(record != null && 1 == record.getState(), "当前计划不存在或已作废！");
        return dao.updateByPrimaryKeySelective(DyeFabricPlan.builder().id(id).markFinished(finished).build());
    }

    /**
     * 修改色布单价
     *
     * @param accountPrice
     * @param planid
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int modifyPriceByPk(BigDecimal accountPrice, Long planid) throws Exception {
        DyeFabricPlan record = dao.selectByPrimaryKey(planid);
        //  校验计划单
        Assert.notNull(record, ResponseEnum.CANCEL_ORDER.getName());
        Assert.state(record.getState() == 1, "单据已作废！");
        Assert.state(!Optional.ofNullable(record).map(DyeFabricPlan::getIsAudit).orElse(false), ResponseEnum.AUDIT_ORDER.getName());
        //  修改单价
        int res = 0;
        res += dao.updateByPrimaryKeySelective(DyeFabricPlan.builder().id(planid).materialPrice(accountPrice).build());
        res += cpBillfhMapper.updateByExampleSelective(
                CpBillfh.builder().accountPrice(accountPrice).build(),
                new Example().andEq("planid", planid));
        res += dyeFabricInboundMapper.updateByExampleSelective(
                DyeFabricInbound.builder().accountPrice(accountPrice).build(),
                new Example().andEq("dye_plan_code", record.getPlanCode()));
        return res;
    }

    /**
     * 获取计价标准
     *
     * @return
     * @throws Exception
     */
    @Override
    public List<Map<String, Object>> getPriceStandard() throws Exception {
        List<Map<String, Object>> result = new ArrayList<>();
        for (PriceStandard e : PriceStandard.values()) {
            Map<String, Object> map = new HashMap<>();
            map.put("key", e.getName());
            map.put("value", e.getValue());
            result.add(map);
        }
        return result;
    }

    /**
     * 根据主键审核
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int auditById(Long[] id) throws Exception {
        return dao.updateByExampleSelective(DyeFabricPlan.builder().isAudit(true).auditUserId(getLoginUserId()).build(), new Example().andIn("id", id));
    }

    /**
     * 根据主键取消审核
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int cancelAuditById(Long[] id) throws Exception {
        DyeFabricPlan record = DyeFabricPlan.builder().isAudit(false).auditUserId(0).build();
        int ret = dao.updateByExampleSelective(record, new Example().andIn("id", id));
        return ret;
    }
}